<?php

namespace app\app\model\order;

use app\admin\model\Admin;
use app\admin\model\goods\GoodsSkuModel;
use app\admin\model\shop\Message;
use app\admin\model\shop\ShopGoodsStockLogModel;
use app\api\model\Order;
use app\app\model\shop\BoardModel;
use app\app\model\shop\ShopGoodsModel;
use app\common\model\Bill;
use app\common\model\GoodsOrderCounter;
use think\Db;
use think\Exception;
use think\Model;
use traits\model\SoftDelete;

class GoodsOrderModel extends Model
{
    use SoftDelete;

    // 表名
    protected $name = 'goods_order';

    // 自动写入时间戳字段
    protected $autoWriteTimestamp = 'integer';

    // 定义时间戳字段名
    protected $createTime = 'createtime';
    protected $updateTime = 'updatetime';
    protected $deleteTime = 'deletetime';

    public const STATUS_DZF = 100;//待支付
    public const STATUS_YZF = 200;//已支付
    public const STATUS_QX = 300;//已取消
    public const STATUS_ZF = 400;//已废弃


    public const STATUS_ARRAY_TEXT = [
        self::STATUS_DZF => 'Not paid',
        self::STATUS_YZF => 'Paid',
        self::STATUS_QX => 'Cancel',
        self::STATUS_ZF => 'Abandoned',
    ];


    public const PAY_TYPE_CASH = 100;// 现金支付
    public const PAY_TYPE_TNG = 200;// TNG
    public const PAY_TYPE_CARD = 300;// 信用卡
    public const PAY_TYPE_SCORE = 400;// 积分

    public const PAY_TYPE_ARRAY_TEXT = [
        0 => '-',
        self::PAY_TYPE_CASH => 'Cash',
        self::PAY_TYPE_TNG => 'TNG',
        self::PAY_TYPE_CARD => 'Credit card',
        self::PAY_TYPE_SCORE => 'Score',
    ];


    public const TYPE_TS = 100; //堂食
    public const TYPE_DB = 200; //打包
    public const TYPE_WM = 300; //外卖

    public const TYPE_ARRAY_TEXT = [
        self::TYPE_TS => 'Dine In',
        self::TYPE_DB => 'Takeout',
        self::TYPE_WM => 'Delivery',
    ];


    /**
     * Notes: 创建订单
     * User: chenLei
     * Date: 8/5/25
     * @param $params
     * @return false|string
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     * @throws \think\exception\PDOException
     */
    public function createOrder($params)
    {

        $discount_amount = 0;
        $discount_goods_id = 0;
        $discount_goods_id_use = false;
        if (!empty($params['voucher_id'])) {
            $voucher_info = Order::where('id', $params['voucher_id'])->find();
            if (empty($voucher_info)) {
                $this->error = 'The coupon doesnt exist.';
                return false;
            }
            if ($voucher_info->expire_time <= time()) {
                $this->error = 'This coupon has expired';
                return false;
            }
            if ($voucher_info->is_use != 0) {
                $this->error = 'This coupon has already been used';
                return false;
            }
            if ($voucher_info->categorys_id == 1) {
                $discount_amount = $voucher_info['money'];
            } else if ($voucher_info->categorys_id == 2) {
                $discount_goods_id = $voucher_info['goods_id'];
            } else {
                $this->error = 'The coupon type is incorrect';
                return false;
            }


        }


        $params['pay_method'] = Message::where('id', $params['shop_id'])->value('pay_method'); //店铺支付方式

        if ($params['type'] == 100) {
            if (empty($params['board_number'])) {
                $this->error = 'For dining-in type orders, please select table number';
                return false;
            }
            //当前 桌子 是否还存在未支付订单  存在则不允许下单
            $list = BoardOrderModel::where('number', $params['board_number'])->where('shop_id', $params['shop_id'])
                ->select();
            foreach ($list as $value) {
                if ($this->where('order_no', $value['order_no'])->where('status', 100)->count()) {
                    $this->error = 'The current table number cannot be used to add new orders. Please modify the order';
                    return false;
                }
            }
        }


        $order_child = [];
        $order_amount = 0;
        $pack_fee_amount = 0;
        foreach ($params['goods'] as $item) {
            if (empty($item['type']) || !in_array($item['type'], [100, 200, 300])) {
                $this->error = 'The sub-product type is incorrect';
                return false;
            }

            $goods_params = [
                'shop_id' => $params['shop_id'],
                'id' => $item['goods_id'],
            ];

            $shopGoodsModel = new ShopGoodsModel();
            $goods = $shopGoodsModel->info($goods_params);

            if ($goods === false) {
                $this->error = $shopGoodsModel->getError();
                return false;
            }
            if ($goods['stock'] < $item['number']) {
                $this->error = $goods['name'] . '/' . $goods['en_name'] . ' short supply';
                return false;
            }
            $sku_name = '';
            $sku_price = 0;
            if (!empty($item['sku_id'])) {   // SKU 价格处理  sku 的价格可以为0
                $sku_array = explode(',', $item['sku_id']);
                foreach ($sku_array as $key => $value) {
                    $goodsSkuModel = new GoodsSkuModel();
                    $sku = $goodsSkuModel->where('id', $value)->find();
                    if (empty($sku)) {
                        $key += 1;
                        $this->error = 'The ' . $key . ' sku does not exist';
                        return false;
                    }
                    if ($sku_name == '') {
                        $sku_name = $sku['cn_name'] . '/' . $sku['en_name'];
                    } else {
                        $sku_name .= ',' . $sku['cn_name'] . '/' . $sku['en_name'];
                    }
                    $sku_price = round($sku_price + $sku['price'], 2);
                }
            }
            $sum_pack_fee = 0;
            $pack_fee = 0;

            if ($item['type'] == self::TYPE_DB) {
                $pack_fee = Message::where('id', $params['shop_id'])->value('pack_fee');  //店铺打包费
                $sum_pack_fee = round($item['number'] * $pack_fee, 2); // 单商品打包费总价
            }

            if ($discount_goods_id == $goods['id'] && $discount_goods_id_use === false) { //如果有抵扣商品
                $discount_amount = $goods['price'];
                $discount_goods_id_use = true;
            }

            $find_price = round($goods['price'] + $sku_price, 2);  // 商品价格 + sku价格
            $sum_price = round($find_price * $item['number'], 2); // 单商品总价
            $pack_fee_amount = round($pack_fee_amount + $sum_pack_fee, 2); //订单打包总价格
            $order_amount = round($order_amount + $sum_price + $sum_pack_fee, 2); // 订单总额
            $order_child[] = [
                'goods_id' => $goods['id'],
                'goods_name' => $goods['name'] . '/' . $goods['en_name'],
                'goods_image' => removeDomain($goods['image']),
                'number' => $item['number'],
                'price' => $goods['price'],
                'sku_price' => $sku_price,
                'pack_fee' => $pack_fee,
                'sum_pack_fee' => $sum_pack_fee,
                'find_price' => $find_price,
                'sum_price' => $sum_price,
                'discount_price' => 0,
                'difference' => $sku_name,
                'sku_data' => $item['sku_id'],
                'type' => $item['type'],
                'remark' => $item['remark'] ?? '',
                'createtime' => time(),
            ];
        }

        if(!empty($discount_goods_id) && $discount_goods_id_use === false){
            $this->error = 'The discounted product does not exist';
            return false;
        }

        if ($order_amount <= 0) {
            $this->error = 'Abnormal payment amount';
            return false;
        }
        $real_amount = $order_amount;
        if ($discount_amount > 0) {
            $real_amount = round($order_amount - $discount_amount, 2);
            $real_amount = $real_amount < 0 ? 0 : $real_amount;
        }

        $order_no = generateOrderNo();
        $order = [
            'serial_number' => GoodsOrderCounter::generate($params['shop_id']),
            'admin_id' => $params['admin_id'],
            'shop_id' => $params['shop_id'],
            'order_no' => $order_no,
            'board_number' => $params['board_number'] ?? 0,
            'pack_fee_amount' => $pack_fee_amount,
            'amount' => $order_amount,
            'real_amount' => $real_amount,
            'discount_amount' => $discount_amount,
            'type' => $params['type'],
            'pay_method' => $params['pay_method'],
            'status' => self::STATUS_DZF,
            'remark' => $params['remark'] ?? '',
            'voucher_id' => $params['voucher_id'] ?? 0,
        ];

        $this->startTrans();
        try {

            $this->save($order);

            foreach ($order_child as &$child) {
                $child['order_id'] = $this->id;
            }
            $goodsOrderChildModel = new GoodsOrderChildModel();
            $goodsOrderChildModel->insertAll($order_child);


            $time = time();
            //商品扣除库存

            foreach ($order_child as $value) {
                $shopGoodsModel = new ShopGoodsModel();
                $info = $shopGoodsModel->where(['shop_id' => $order['shop_id'], 'goods_id' => $value['goods_id']])->find();
                $before = $info->stock;
                $after = $info->stock - $value['number'];

                $info->stock = $after;
                $info->save();

                ShopGoodsStockLogModel::add([
                    'shop_id' => $order['shop_id'],
                    'goods_id' => $value['goods_id'],
                    'number' => $value['number'],
                    'before' => $before,
                    'after' => $after,
                    'type' => ShopGoodsStockLogModel::TYPE_ORDER,
                    'order_id' => $this->id,
                    'op_admin_id' => $params['admin_id'],
                    'createtime' => $time
                ]);
            }

            if ($params['pay_method'] == 200 && !empty($params['board_number']) && $params['type'] == self::TYPE_TS) {

                BoardModel::where(['shop_id' => $params['shop_id'], 'number' => $params['board_number']])
                    ->update(['status' => BoardModel::STATUS_OCCUPIED]);

                BoardOrderModel::insert([
                    'number' => $params['board_number'],
                    'shop_id' => $params['shop_id'],
                    'order_no' => $order_no,
                    'status' => 200,
                    'createtime' => time(),
                ]);
            }


            $this->commit();
        } catch (Exception $exception) {
            $this->rollback();
            $this->error = $exception->getMessage();
            return false;
        }

        return $order_no;
    }


    /**
     * Notes: 更新订单商品 只添加 不修改
     * User: chenLei
     * Date: 8/13/25
     * @param $params
     * @return bool
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     * @throws \think\exception\PDOException
     */
    public function updateOrder($params)
    {
        $order = $this->where('order_no', $params['order_no'])->find();
        if (empty($order)) {
            $this->error = 'Order not found';
            return false;
        }

        if ($order->status != self::STATUS_DZF) {
            $this->error = 'The order is not in pending payment status and cannot be edited';
            return false;
        }

        $order_child = [];
        $order_amount = 0;
        $pack_fee_amount = 0;
        foreach ($params['goods'] as $item) {
            $goods_params = [
                'shop_id' => $params['shop_id'],
                'id' => $item['goods_id'],
            ];

            $shopGoodsModel = new ShopGoodsModel();
            $goods = $shopGoodsModel->info($goods_params);

            if ($goods === false) {
                $this->error = $shopGoodsModel->getError();
                return false;
            }
            if ($goods['stock'] < $item['number']) {
                $this->error = $goods['name'] . '/' . $goods['en_name'] . ' short supply';
                return false;
            }
            $sku_name = '';
            $sku_price = 0;
            if (!empty($item['sku_id'])) {   // SKU 价格处理  sku 的价格可以为0
                $sku_array = explode(',', $item['sku_id']);
                foreach ($sku_array as $key => $value) {
                    $goodsSkuModel = new GoodsSkuModel();
                    $sku = $goodsSkuModel->where('id', $value)->find();
                    if (empty($sku)) {
                        $key += 1;
                        $this->error = 'The ' . $key . ' sku does not exist';
                        return false;
                    }
                    if ($sku_name == '') {
                        $sku_name = $sku['cn_name'] . '/' . $sku['en_name'];
                    } else {
                        $sku_name .= ',' . $sku['cn_name'] . '/' . $sku['en_name'];
                    }
                    $sku_price = round($sku_price + $sku['price'], 2);
                }
            }

            $sum_pack_fee = 0;
            $pack_fee = 0;

            if ($order['type'] == self::TYPE_DB) {
                $pack_fee = Message::where('id', $params['shop_id'])->value('pack_fee');  //店铺打包费
                $sum_pack_fee = round($item['number'] * $pack_fee, 2); // 单商品打包费总价
            }

            $find_price = round($goods['price'] + $sku_price, 2);
            $sum_price = round($find_price * $item['number'], 2);
            $pack_fee_amount = round($pack_fee_amount + $sum_pack_fee, 2); //订单打包总价格
            $order_amount = round($order_amount + $sum_price + $sum_pack_fee, 2);  //订单总价
            $order_child[] = [
                'order_id' => $order['id'],
                'goods_id' => $goods['id'],
                'goods_name' => $goods['name'] . '/' . $goods['en_name'],
                'goods_image' => removeDomain($goods['image']),
                'number' => $item['number'],
                'pack_fee' => $pack_fee,
                'sum_pack_fee' => $sum_pack_fee,
                'price' => $goods['price'],
                'sku_price' => $sku_price,
                'find_price' => $find_price,
                'sum_price' => $sum_price,
                'discount_price' => 0,
                'difference' => $sku_name,
                'sku_data' => $item['sku_id'],
                'createtime' => time(),
            ];
        }

        if ($order_amount <= 0) {
            $this->error = 'Abnormal payment amount';
            return false;
        }


        $this->startTrans();
        try {

            $order->amount = round($order->amount + $order_amount, 2);
            $order->real_amount = round($order->real_amount + $order_amount, 2);
            $order->pack_fee_amount = round($order->pack_fee_amount + $pack_fee_amount, 2);
            $order->save();

            $goodsOrderChildModel = new GoodsOrderChildModel();
            $goodsOrderChildModel->insertAll($order_child);


            $time = time();
            //商品扣除库存

            foreach ($order_child as $value) {
                $shopGoodsModel = new ShopGoodsModel();
                $info = $shopGoodsModel->where(['shop_id' => $order['shop_id'], 'goods_id' => $value['goods_id']])->find();
                $before = $info->stock;
                $after = $info->stock - $value['number'];

                $info->stock = $after;
                $info->save();

                ShopGoodsStockLogModel::add([
                    'shop_id' => $order['shop_id'],
                    'goods_id' => $value['goods_id'],
                    'number' => $value['number'],
                    'before' => $before,
                    'after' => $after,
                    'type' => ShopGoodsStockLogModel::TYPE_ORDER,
                    'order_id' => $order['id'],
                    'op_admin_id' => $params['admin_id'],
                    'createtime' => $time
                ]);
            }


            $this->commit();
        } catch (Exception $exception) {
            $this->rollback();
            $this->error = $exception->getMessage();
            return false;
        }

        return true;
    }


    /**
     * Notes: 修改订单
     * User: chenLei
     * Date: 8/7/25
     * @param $params
     * @return bool
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     * @throws \think\exception\PDOException
     */
    public function edit($params)
    {
        $order = $this->where('order_no', $params['order_no'])->find();

        if (empty($order)) {
            $this->error = 'The order does not exist.';
            return false;
        }
        if ($order->status != self::STATUS_DZF) {
            $this->error = 'This order status is not "Pending Payment" and cannot be modified';
            return false;
        }


        $this->startTrans();
        try {
            $this->rollStock($order); // 优先退回库存

            $order_child = [];
            $order_amount = 0; //订单总价
            $pack_fee_amount = 0; //打包总价
            foreach ($params['goods'] as $item) {
                $goods_params = [
                    'shop_id' => $params['shop_id'],
                    'id' => $item['goods_id'],
                ];

                $shopGoodsModel = new ShopGoodsModel();
                $goods = $shopGoodsModel->info($goods_params);

                if ($goods === false) {
                    $this->error = $shopGoodsModel->getError();
                    return false;
                }
                if ($goods['stock'] < $item['number']) {
                    $this->error = $goods['name'] . '/' . $goods['en_name'] . ' short supply';
                    return false;
                }
                $sku_name = '';
                $sku_price = 0;
                if (!empty($item['sku_id'])) {   // SKU 价格处理  sku 的价格可以为0
                    $sku_array = explode(',', $item['sku_id']);
                    foreach ($sku_array as $key => $value) {
                        $goodsSkuModel = new GoodsSkuModel();
                        $sku = $goodsSkuModel->where('id', $value)->find();
                        if (empty($sku)) {
                            $key += 1;
                            $this->error = 'The ' . $key . ' sku does not exist';
                            return false;
                        }
                        if ($sku_name == '') {
                            $sku_name = $sku['cn_name'] . '/' . $sku['en_name'];
                        } else {
                            $sku_name .= ',' . $sku['cn_name'] . '/' . $sku['en_name'];
                        }
                        $sku_price = round($sku_price + $sku['price'], 2);
                    }
                }
                $find_price = round($goods['price'] + $sku_price, 2);
                $sum_price = round($find_price * $item['number'], 2);
                $order_amount = round($order_amount + $sum_price, 2);
                $order_child[] = [
                    'order_id' => $order['id'],
                    'goods_id' => $goods['id'],
                    'goods_name' => $goods['name'] . '/' . $goods['en_name'],
                    'goods_image' => removeDomain($goods['image']),
                    'number' => $item['number'],
                    'price' => $goods['price'],
                    'sku_price' => $sku_price,
                    'find_price' => $find_price,
                    'sum_price' => $sum_price,
                    'discount_price' => 0,
                    'difference' => $sku_name,
                    'sku_data' => $item['sku_id'],
                    'createtime' => time(),
                ];
            }

            if ($order_amount <= 0) {
                $this->error = 'Abnormal payment amount';
                return false;
            }


            $order_data = [
                'board_number' => $params['board_number'] ?? 0,
                'amount' => $order_amount,
                'real_amount' => $order_amount,
            ];

            $order->save($order_data);


            $goodsOrderChildModel = new GoodsOrderChildModel();
            $goodsOrderChildModel->where('order_id', $order['id'])->delete();
            $goodsOrderChildModel->insertAll($order_child);

            $time = time();
            //商品扣除库存

            foreach ($order_child as $value) {
                $shopGoodsModel = new ShopGoodsModel();
                $info = $shopGoodsModel->where(['shop_id' => $order['shop_id'], 'goods_id' => $value['goods_id']])->find();
                $before = $info->stock;
                $after = $info->stock - $value['number'];

                $info->stock = $after;
                $info->save();

                ShopGoodsStockLogModel::add([
                    'shop_id' => $order['shop_id'],
                    'goods_id' => $value['goods_id'],
                    'number' => $value['number'],
                    'before' => $before,
                    'after' => $after,
                    'type' => ShopGoodsStockLogModel::TYPE_ORDER,
                    'order_id' => $order['id'],
                    'op_admin_id' => $params['admin_id'],
                    'createtime' => $time
                ]);
            }


            $this->commit();
        } catch (\Exception $exception) {
            $this->rollback();
            $this->error = $exception->getMessage();
            return false;
        }


        return $params['order_no'];

    }


    /**
     * Notes: 支付成功的回调方法
     * User: chenLei
     * Date: 8/4/25
     * @param $order_no
     * @param $pay_type 支付方式
     * @return false|void
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public function successOrder($params)
    {


        $order = $this->where('order_no', $params['order_no'])->find();
        if (empty($order)) {
            $this->error = 'The order does not exist.';
            return false;
        }

        if ($order->status != self::STATUS_DZF) {
            $this->error = 'The order status is not "Pending payment"';
            return false;
        }

        if ($params['pay_type'] == self::PAY_TYPE_CASH) {
            if ($params['cash_amount'] < $order['real_amount']) {
                $this->error = 'The amount of cash payment is less than the order amount';
                return false;
            }
        }


        $this->startTrans();
        try {

            if ($params['pay_type'] == self::PAY_TYPE_CASH && $order['real_amount'] > $params['cash_amount']) {
                $order->cash_amount = $params['cash_amount'];
                $order->cash_change = round($order['cash_amount'] - $params['real_amount'], 2);
            }

            $order->status = self::STATUS_YZF;
            $order->pay_type = $params['pay_type'];
            $order->pay_time = time();
            $order->save();


            //桌号占用
            if ($order['type'] == 100) { // 堂食


                if ($order->pay_method == 200) {  // 后面支付类型  清桌

                    BoardModel::where([
                        'shop_id' => $order['shop_id'],
                        'number' => $order['board_number']
                    ])->update(['status' => 100]);

                    BoardOrderModel::where(['shop_id' => $order['shop_id'], 'number' => $order['board_number'],
                        'status' => 200])->update(['status' => 100, 'settle_time' => time()]);

                } else if ($order->pay_method == 100) { // 如果是现结  桌子更新使用中状态 并且加上订单信息

                    BoardModel::where([
                        'shop_id' => $order['shop_id'],
                        'number' => $order['board_number']
                    ])->update(['status' => 200]);

                    BoardOrderModel::insert([
                        'number' => $order['board_number'],
                        'shop_id' => $order['shop_id'],
                        'order_no' => $order['order_no'],
                        'status' => 200,
                        'createtime' => time(),
                    ]);
                }
            }

            (new Bill())->save([
                'shop_id' => $order['shop_id'],
                'type' => Bill::TYPE_ORDER,
                'be' => 1,
                'money' => $order['real_amount'],
                'order_id' => $order['id'],
                'admin_id' => $params['admin_id'],
                'memo' => $params['admin_id'],
            ]);


            //处理优惠券
            if(!empty($order['voucher_id'])){
                $voucher = Order::where('id',$order['voucher_id'])->find();
                if(!empty($voucher)){
                    $voucher->is_use = 1;
                    $voucher->use_time = time();
                    $voucher->goods_order_id = $order['id'];
                    $voucher->save();
                }
            }

            $this->commit();
        } catch (Exception $exception) {
            $this->rollback();
            $this->error = $exception->getMessage();
            return false;
        }

        return true;

    }


    /**
     * Notes: 订单详情
     * User: chenLei
     * Date: 8/5/25
     * @param $params
     * @return array|false
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public function info($params)
    {
        $order = $this->where('order_no', $params['order_no'])->field('data_json', true)->find();
        if (empty($order)) {
            $this->error = 'The order does not exist.';
            return false;
        }

        $order['createtime'] = date('Y-m-d H:i:s', $order['createtime']);
        $order['pay_time'] = $order['pay_time'] ? date('Y-m-d H:i:s', $order['pay_time']) : '-';
        $order['cancel_time'] = $order['cancel_time'] ? date('Y-m-d H:i:s', $order['cancel_time']) : '-';
        $child = GoodsOrderChildModel::where('order_id', $order['id'])->order('id desc')->select();

        foreach ($child as &$item) {
            $item['code'] = Db::name('goods')->where('id', $item['goods_id'])->value('code');
        }

        $order['child'] = $child;
        return $order;
    }

    /**
     * Notes: 自动取消订单
     * User: chenLei
     * Date: 8/6/25
     * @return true
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     * @throws \think\exception\PDOException
     */
    public function autoCancelOrder()
    {
        $min = 30;

        $list = $this->where('createtime', '<', time() - $min * 60)
            ->field('order_no')
            ->select();

        foreach ($list as $value) {
            $this->createOrder(['order_no' => $value['order_no']]);
        }

        return true;

    }

    /**
     * Notes: 取消订单
     * User: chenLei
     * Date: 8/5/25
     * @param $params
     * @return false|void
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public function cancelOrder($params)
    {
        $order = $this->where('order_no', $params['order_no'])->find();
        if (empty($order)) {
            $this->error = 'The order does not exist.';
            return false;
        }

        if ($order->status != self::STATUS_DZF) {
//            $this->error = 'The order status is not "Pending payment"';
//            return false;
        }

        $this->startTrans();
        try {

            if ($order->status == self::STATUS_DZF) {
                $status = self::STATUS_QX;
            } else if ($order->status == self::STATUS_YZF) {
                $status = self::STATUS_ZF;
                $billModel = new Bill();
                $billModel->invalid($order['id']);
            }
            $order->status = $status;
            $order->cancel_time = time();
            $order->save();

            if ($this->rollStock($order) === false) {
                \exception($this->getError());
            }

            $this->commit();
        } catch (Exception $exception) {
            $this->rollback();
            $this->error = $exception->getMessage();
            return false;
        }
        return true;
    }


    /**
     * Notes: 退回库存
     * User: chenLei
     * Date: 8/7/25
     * @param $order
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public function rollStock($order)
    {
        try {
            $orderChild = new GoodsOrderChildModel();
            $order_child = $orderChild->where('order_id', $order['id'])->select();
            $time = time();
            foreach ($order_child as $value) {
                $shopGoodsModel = new ShopGoodsModel();
                $info = $shopGoodsModel->where(['shop_id' => $order['shop_id'], 'goods_id' => $value['goods_id']])->find();
                $before = $info->stock;
                $after = $info->stock + $value['number'];

                $info->stock = $after;
                $info->save();

                ShopGoodsStockLogModel::add([
                    'shop_id' => $order['shop_id'],
                    'goods_id' => $value['goods_id'],
                    'number' => $value['number'],
                    'before' => $before,
                    'after' => $after,
                    'type' => ShopGoodsStockLogModel::TYPE_ROLL,
                    'order_id' => $order['id'],
                    'op_admin_id' => $params['admin_id'] ?? 0,
                    'createtime' => $time
                ]);
            }

        } catch (Exception $exception) {
            $this->error = '库存退回异常' . $exception->getMessage();
            return false;
        }
        return true;
    }

    /**
     * Notes: 订单列表
     * User: chenLei
     * Date: 8/5/25
     * @param $params
     * @return \think\Paginator
     * @throws \think\db\exception\DbException
     */
    public function list($params)
    {
        $where = [];
        $where['shop_id'] = ['=', $params['shop_id']];

        if (!empty($params['order_no'])) {
            $where['order_no'] = ['=', $params['order_no']];
        }
        if (!empty($params['status'])) {
            $where['status'] = ['=', $params['status']];
        }
        if (!empty($params['type'])) {
            $where['type'] = ['=', $params['type']];
        }
        if (!empty($params['pay_type'])) {
            $where['pay_type'] = ['=', $params['pay_type']];
        }
        if (!empty($params['pay_method'])) {
            $where['pay_method'] = ['=', $params['pay_method']];
        }
        if (!empty($params['pay_time'])) {
            $where['pay_time'] = ['between time', explode(' - ', $params['pay_time'])];
        }
        if (!empty($params['createtime'])) {
            $where['createtime'] = ['between time', explode(' - ', $params['createtime'])];
        }

        return $this->where($where)->order('serial_number asc')
            ->field('data_json', true)
            ->paginate($params['page_size'] ?? 15)->each(function ($item) {

                $item['pay_type_text'] = self::PAY_TYPE_ARRAY_TEXT[$item['pay_type']] ?? '-';
                $item['status_text'] = self::STATUS_ARRAY_TEXT[$item['status']] ?? '-';
                $item['pay_method_text'] = $item['pay_method'] == 100 ? 'Cash' : 'Pre-order';
                $item['type_text'] = self::TYPE_ARRAY_TEXT[$item['type']];
                $item['hour'] = date('H:i', $item['createtime']);
                $item['cancel_time'] = $item['cancel_time'] != 0 ? date('Y-m-d H:i:s', $item['cancel_time']) : "-";
                $item['pay_time'] = $item['pay_time'] != 0 ? date('Y-m-d H:i:s', $item['pay_time']) : "-";
                $item['createtime'] = date('Y-m-d H:i:s', $item['createtime']);
            });
    }

    /**
     * Notes: 清桌
     * User: chenLei
     * Date: 8/7/25
     * @param $params
     * @return false|void
     * @throws Exception
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     * @throws \think\exception\PDOException
     */
    public function clearTable($params)
    {
        $list = BoardOrderModel::where('number', $params['board_number'])->where('shop_id', $params['shop_id'])
            ->where('status', 200)->select();
        if (count($list) <= 0) {
            BoardModel::where(['shop_id' => $params['shop_id'], 'number' => $params['board_number']])->update
            (['status' => BoardModel::STATUS_AVAILABLE]);
        } else {
//            foreach ($list as $value) {
//                if ($this->where('order_no', $value['order_no'])->where('pay_method', 200)->count()) {
//                    $this->error = '支付还未开发';
//                    return false;
//                }
//            }

            $this->startTrans();
            try {
                BoardModel::where(['shop_id' => $params['shop_id'], 'number' => $params['board_number']])
                    ->update(['status' => BoardModel::STATUS_AVAILABLE]);

                BoardOrderModel::where('number', $params['board_number'])
                    ->where('shop_id', $params['shop_id'])
                    ->where('status', 200)->update(['status' => 100, 'settle_time' => time()]);


                $this->commit();
            } catch (Exception $exception) {
                $this->rollback();
                $this->error = $exception->getMessage();
                return false;
            }
        }

        return true;
    }


    /**
     * Notes: 桌号订单详情
     * User: chenLei
     * Date: 8/7/25
     * @param $params
     * @return array
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public function boardInfo($params)
    {
        $info = BoardOrderModel::where('number', $params['board_number'])->where('shop_id', $params['shop_id'])
            ->where('status', 200)->order('id desc ')->find();
        if (empty($info)) {
            return [];
        }

        $data = $this->info(['order_no' => $info['order_no']]);

        if ($data['pay_method'] == 100) {  //如果是现结  返回空
            return [];
        }

        return $data;
    }


    /**
     * Notes: 分屏获取商品信息
     * User: chenLei
     * Date: 8/17/25
     * @param $params
     * @return array|false
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public function goodsListInfo($params)
    {
        $params['shop_id'] = $params['shopId'];
        $params['pay_method'] = Message::where('id', $params['shop_id'])->value('pay_method'); //店铺支付方式

        $order_child = [];
        $order_amount = 0;
        $pack_fee_amount = 0;
        foreach ($params['goods'] as $item) {
            if (empty($item['type']) || !in_array($item['type'], [100, 200, 300])) {
                $this->error = 'The sub-product type is incorrect';
                return false;
            }

            $goods_params = [
                'shop_id' => $params['shop_id'],
                'id' => $item['goods_id'],
            ];

            $shopGoodsModel = new ShopGoodsModel();
            $goods = $shopGoodsModel->info($goods_params);

            if ($goods === false) {
                $this->error = $shopGoodsModel->getError();
                return false;
            }
            if ($goods['stock'] < $item['number']) {
                $this->error = $goods['name'] . '/' . $goods['en_name'] . ' short supply';
                return false;
            }
            $sku_name = '';
            $sku_price = 0;
            if (!empty($item['sku_id'])) {   // SKU 价格处理  sku 的价格可以为0
                $sku_array = explode(',', $item['sku_id']);
                foreach ($sku_array as $key => $value) {
                    $goodsSkuModel = new GoodsSkuModel();
                    $sku = $goodsSkuModel->where('id', $value)->find();
                    if (empty($sku)) {
                        $key += 1;
                        $this->error = 'The ' . $key . ' sku does not exist';
                        return false;
                    }
                    if ($sku_name == '') {
                        $sku_name = $sku['cn_name'] . '/' . $sku['en_name'];
                    } else {
                        $sku_name .= ',' . $sku['cn_name'] . '/' . $sku['en_name'];
                    }
                    $sku_price = round($sku_price + $sku['price'], 2);
                }
            }
            $sum_pack_fee = 0;
            $pack_fee = 0;

            if ($item['type'] == self::TYPE_DB) {
                $pack_fee = Message::where('id', $params['shop_id'])->value('pack_fee');  //店铺打包费
                $sum_pack_fee = round($item['number'] * $pack_fee, 2); // 单商品打包费总价
            }

            $find_price = round($goods['price'] + $sku_price, 2);  // 商品价格 + sku价格
            $sum_price = round($find_price * $item['number'], 2); // 单商品总价
            $pack_fee_amount = round($pack_fee_amount + $sum_pack_fee, 2); //订单打包总价格
            $order_amount = round($order_amount + $sum_price + $sum_pack_fee, 2); // 订单总额
            $order_child[] = [
                'goods_id' => $goods['id'],
                'goods_name' => $goods['name'] . '/' . $goods['en_name'],
                'goods_image' => Https($goods['image']),
                'number' => $item['number'],
                'price' => $goods['price'],
                'sku_price' => $sku_price,
                'pack_fee' => $pack_fee,
                'sum_pack_fee' => $sum_pack_fee,
                'find_price' => $find_price,
                'sum_price' => $sum_price,
                'discount_price' => 0,
                'difference' => $sku_name,
                'sku_data' => $item['sku_id'],
                'type' => $item['type'],
                'remark' => $item['remark'] ?? '',
                'createtime' => time(),
            ];
        }


        $order = [
            'board_number' => $params['board_number'] ?? 0,
            'pack_fee_amount' => $pack_fee_amount,
            'amount' => $order_amount,
            'real_amount' => $order_amount,
            'pay_method' => $params['pay_method'],
            'status' => self::STATUS_DZF,
            'remark' => $params['remark'] ?? '',
            'order_child' => $reverse = array_reverse($order_child),
        ];

        return $order;
    }
}